package com.ling.common.library.base.mvi

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

/**
 * @author Ling
 * @date :2024/8/23 11:50
 */
abstract class IViewModel<UiIntent : IUiIntent, UiState : IUiState, UiEvent : IUiEvent> : ViewModel() {

    //页面事件的 Channel 分发
    private val _uiIntent by lazy { Channel<UiIntent>(Channel.UNLIMITED) }
    //一次性ui事件，只响应一次
    private val uiEvent = MutableSharedFlow<UiEvent>() //可变，提供内部调用
    //对内提供
    private val _uiState by lazy {
        val iState = initUiState()
        if(iState == null) null else MutableStateFlow(iState)
    }
    //对外提供
    val uiState by lazy { _uiState!!.asStateFlow() }



    open fun initUiState() : UiState? = null
    protected abstract suspend fun handleIntent(it : UiIntent)

    init {
        viewModelScope.launch {
            //可添加，distinctUntilChanged 去重
            _uiIntent.receiveAsFlow().collect{
                handleIntent(it)
            }
        }
    }

    //更新页面状态
    protected fun updateUiState(uiState: UiState.() -> UiState){
        _uiState?.let {  ui->
            ui.update { uiState(ui.value) }
        }
    }

    fun sendUiIntent(intent : UiIntent){
        viewModelScope.launch {
            _uiIntent.send(intent)
        }
    }

    //发送一次性事件给UI
    protected fun sendUiEvent(event: UiEvent) = viewModelScope.launch {
        uiEvent.emit(event)
    }

    //供页面调用，接收用户事件处理完后的响应数据
    fun handleUiEvent(onUiEvent : (uiEvent : UiEvent) -> Unit){
        //distinctUntilChanged 去重
        viewModelScope.launch {
            uiEvent.collect{
                onUiEvent(it)
            }
        }
    }


    override fun onCleared() {
        super.onCleared()
        _uiIntent.close()
    }
}